#include <iostream>
#include <string>
#include <cstdint>

class AltitudeDisplay
{
private:
    // 常量定义
    static constexpr uint16_t INVALID_VALUE = 0x1FFF;
    static constexpr int16_t MAX_NEGATIVE_DISPLAY = -999;
    static constexpr uint16_t MAX_POSITIVE_DISPLAY = 8190;
    static constexpr uint8_t TIMEOUT_THRESHOLD = 10;

    // 状态变量
    int16_t lastValidValue_ = 0;
    std::string currentDisplay_ = "0m";
    uint8_t signalLostCounter_ = 0;
    bool isPowerOn_ = false;

public:
    AltitudeDisplay() = default;

    // KL30复位处理
    void reset()
    {
        currentDisplay_ = "0m";
        signalLostCounter_ = 0;
        // 注意：lastValidValue_不重置，保持记忆功能
    }

    // KL15电源状态处理
    void setPowerState(bool isOn)
    {
        isPowerOn_ = isOn;
        if (!isOn)
        {
            // 电源关闭时不做特殊处理，仅标记状态
            // 下次上电时会自动使用lastValidValue_
        }
    }

    // 处理海拔信号输入
    void processSignal(uint8_t heiLvlSign, uint16_t heiLvl)
    {
        // 重置信号丢失计数器
        signalLostCounter_ = 0;

        // 处理无效值
        if (heiLvl == INVALID_VALUE)
        {
            return; // 保持上次有效显示
        }

        // 处理0值
        if (heiLvl == 0x0000)
        {
            currentDisplay_ = "0m";
            lastValidValue_ = 0;
            return;
        }

        // 处理有效值范围
        if (heiLvl >= 0x0001 && heiLvl <= 0x1FFE)
        {
            // 计算实际值（文档说明实际值=HeiLvl/2）
            int16_t actualValue = static_cast<int16_t>(heiLvl) / 2;

            // 处理符号
            if (heiLvlSign == 1)
            { // 负数
                // 检查是否超出负值显示范围
                if (actualValue > MAX_NEGATIVE_DISPLAY)
                {
                    return; // 超出范围，保持上次有效值
                }
                currentDisplay_ = "-" + std::to_string(actualValue) + "m";
            }
            else
            { // 正数
                // 检查是否超出正值显示范围
                if (actualValue > MAX_POSITIVE_DISPLAY)
                {
                    return; // 超出范围，保持上次有效值
                }
                currentDisplay_ = std::to_string(actualValue) + "m";
            }

            // 更新最后有效值
            lastValidValue_ = actualValue;
        }
    }

    // 处理信号丢失
    void signalLost()
    {
        signalLostCounter_++;

        if (signalLostCounter_ > TIMEOUT_THRESHOLD)
        {
            // 超时处理，显示最后有效值
            if (lastValidValue_ != 0)
            {
                currentDisplay_ = std::to_string(lastValidValue_) + "m";
            }
            else
            {
                currentDisplay_ = "0m";
            }
        }
    }

    // 获取当前显示值
    const std::string &getDisplay() const
    {
        return currentDisplay_;
    }

    // 获取最后有效值（用于测试）
    int16_t getLastValidValue() const
    {
        return lastValidValue_;
    }
};

// 单元测试
void testAltitudeDisplay()
{
    AltitudeDisplay display;

    // 测试1: 初始状态
    std::cout << "Test 1 - Initial: " << display.getDisplay() << std::endl;

    // 测试2: 正数有效值
    display.processSignal(0, 0x0CC8); // 200
    std::cout << "Test 2 - Positive 200: " << display.getDisplay() << std::endl;

    // 测试3: 负数有效值
    display.processSignal(1, 0x0CC8); // -200
    std::cout << "Test 3 - Negative -200: " << display.getDisplay() << std::endl;

    // 测试4: 超出负值范围
    display.processSignal(1, 0x03E8); // -1000 (超出范围)
    std::cout << "Test 4 - Out of range -1000: " << display.getDisplay() << " (保持-200)" << std::endl;

    // 测试5: 无效值
    display.processSignal(0, 0x1FFF); // 无效
    std::cout << "Test 5 - Invalid value: " << display.getDisplay() << " (保持-200)" << std::endl;

    // 测试6: 信号丢失超时
    for (int i = 0; i < 11; ++i)
    {
        display.signalLost();
    }
    std::cout << "Test 6 - Signal timeout: " << display.getDisplay() << " (显示最后有效值)" << std::endl;

    // 测试7: KL30复位
    display.reset();
    std::cout << "Test 7 - Reset: " << display.getDisplay() << std::endl;

    // 测试8: 电源状态切换
    display.processSignal(0, 0x0BB8); // 300
    display.setPowerState(false);
    display.setPowerState(true);
    std::cout << "Test 8 - Power cycle: " << display.getDisplay() << " (应显示300)" << std::endl;
}

int main()
{
    testAltitudeDisplay();
    return 0;
}